package com.ujn.demo.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ujn.demo.model.ContainerVO;
import com.ujn.demo.model.UserVO;
import com.ujn.demo.service.OperateService;
import com.ujn.demo.util.JacksonUtil;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.UUID;

/**
 * @author sunjx
 * @program uploadTest
 * @description OperateServiceImpl
 * @date 2020-12-28 15:11
 */
@Service
public class OperateServiceImpl implements OperateService {

    private static final String CODE_ENCODING = "UTF-8";

    private static final Logger LOGGER = LoggerFactory.getLogger(OperateServiceImpl.class);

    /**
     * swift.url
     */
    @Value("${swift.url}")
    private String swiftUrl;

    /**
     * tomcat.basedir
     */
    @Value("${tomcat.basedir:C:\\Users\\可爱的小宝贝\\Desktop\\身份证\\0412}")
    private String tomcatBasedir;


    @Override
    public String uploadAndDelete(String objectName, String containerName, String token, MultipartFile multipartFile){
        String result = uploadObjectByStream(objectName, containerName, token, multipartFile);
        deleteObject(containerName, objectName, token);
        return result;
    }


    @Override
    public String uploadObjectByStream(String objectName, String containerName, String token, MultipartFile multipartFile) {
        Double speed = 0.0;
        HttpClient client = new DefaultHttpClient();
        InputStream in = null;
        try {
            in = multipartFile.getInputStream();
        }catch (IOException e) {
            e.printStackTrace();
        }

        String url = "/openstack/swift/object/upload/inputStream";
        LOGGER.info("url--------------------:{} " , swiftUrl +url);
        HttpPost post = new HttpPost(swiftUrl + url);
        String response = "";

        try {
            post.addHeader("Content-Type", "application/octet-stream");
            post.addHeader("Accept", "application/json");
            post.addHeader("tokenId", token);
            post.addHeader("containerName", containerName);
            post.addHeader("objectName", objectName);
            InputStreamEntity re = new InputStreamEntity(in, multipartFile.getSize());
            post.setEntity(re);
            long startTime = System.currentTimeMillis();//获取开始时间
            // 转码,防止中文乱码
            HttpResponse res = client.execute(post);
            long endTime = System.currentTimeMillis();//获取结束时间
            long timeMS = endTime - startTime;//时差ms
            double timeS = timeMS/(double)1000;//时差s，保留小数位
            long lengthK = multipartFile.getSize();//文件大小K
            double lengthM = lengthK/(double)1048576;//文件大小M
            speed = lengthM/timeS;//速度MB/S（精确值）
            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("--------------------Post " + url + " ResultCode : " + statusCode);
            LOGGER.info("--------------------Post url:{},ResultCode:{}" + swiftUrl +url ,statusCode);
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString(entity, CODE_ENCODING);
            LOGGER.info("--------------------response : " + response);
            System.out.println("--------------------response : " + response);
            System.out.println("文件上传时间(s)：" + timeS + "s");//输出程序运行时间(s)
            System.out.println("文件大小为："+ lengthM + "M");//输出文件大小(M)
            System.out.println("文件上传速度为："+ speed + "MB/S");//输出文件上传速度(M/S)
            String result = "statusCode: " + statusCode + ";文件上传时间(s)：" + timeS + "s;" + "大小为："+ lengthM + "M;" +  "上传速度为："+ speed + "MB/S";
            return result ;
        } catch (Exception e) {
            e.printStackTrace();
            return "上传失败";
        }
    }

    @Override
    public String downloadObjectByStream(String containerName, String objectName, String token) {
        Double speed = 0.0;
        HttpClient client = new DefaultHttpClient();
        String url = "/openstack/swift/object/download/inputStream";
        HttpPost post = new HttpPost(swiftUrl + url);
        LOGGER.info("url--------------------: " + swiftUrl + url);
        String response = "";
        String result = "";
        try {
//            post.addHeader("Content-Type", "application/json");
            post.addHeader("Accept", "application/octet-stream");
            post.addHeader("tokenId", token);
            post.addHeader("containerName", containerName);
            post.addHeader("objectName", objectName);
            long startTime = System.currentTimeMillis();    //获取开始时间
            // 转码,防止中文乱码
            HttpResponse res = client.execute(post);
            long endTime = System.currentTimeMillis();//获取结束时间
            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("--------------------post " + url + " ResultCode : " + statusCode);
            if (statusCode == 200 || statusCode == 201) {
                HttpEntity entity = res.getEntity();
                InputStream in = entity.getContent();
                String[] str = objectName.split("\\.");
                String newName = UUID.randomUUID().toString() + "." + str[1];
                OutputStream os = new FileOutputStream(new File(tomcatBasedir + newName));

                os.write(IOUtils.toByteArray(in));
                in.close();
                os.close();
                LOGGER.info("--------------------文件写入完成 ");
                File file = new File(tomcatBasedir + newName);
                long timeMS = endTime - startTime;//时差ms
                double timeS = timeMS/(double)1000;//时差s，保留小数位
                long lengthK = file.length();//文件大小K
                double lengthM = lengthK/(double)1048576;//文件大小M
                speed = lengthM/timeS;//速度MB/S（精确值）
                speed = (double) Math.round(speed * 100) / 100;//速度MB/S（保留两位小数，四舍五入）
                System.out.println("文件下载时间(s)：" + timeS + "s");//输出程序运行时间(s)
                System.out.println("文件大小为："+ lengthM + "M");//输出文件大小(M)
                System.out.println("文件下载速度为："+ speed + "MB/S");//输出文件上传速度(M/S)
                result = "statusCode: " + statusCode + ";文件下载时间(s)：" + timeS + "s;" + "大小为："+ lengthM + "M;" +  "下载速度为："+ speed + "MB/S";
            } else {
                HttpEntity entity = res.getEntity();
                response = EntityUtils.toString(entity, CODE_ENCODING);
                LOGGER.info("--------------------response : " + response);
                result = response;
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return "下载失败";
        }
    }

    @Override
    public String getNewToken() {
        String tokenId = "null";
        UserVO userVO = new UserVO();
        userVO.setProjectDomain("default");
        userVO.setUserDomain("default");
        userVO.setName("swift");
       // userVO.setPassword("Sitech.2019!");
        userVO.setPassword("service");
        userVO.setTenantName("service");

        HttpClient client = new DefaultHttpClient();
        String url = swiftUrl  + "/openstack/identity/v3/token/getnew";
        HttpPost post = new HttpPost(url);
        System.out.println("url:"  + url);
        String response = "";
        try {
            post.addHeader("Content-Type", "application/json;charset=" + CODE_ENCODING);
            post.addHeader("Accept", "application/json");
            String clazzToJson = JacksonUtil.toJson(userVO);
            // 转码,防止中文乱码
            StringEntity s = new StringEntity(clazzToJson, CODE_ENCODING);
            post.setEntity(s);
            HttpResponse res = client.execute(post);

            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("==========================Post " + url + " Data " + clazzToJson + " ResultCode : " + statusCode);
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString(entity, CODE_ENCODING);
            System.out.println("==========================response : " + response);
            JSONObject parseObject = JSON.parseObject(response);
            tokenId = parseObject.getString("tokenId");
        } catch (Exception e) {
            e.printStackTrace();
        }
        LOGGER.info("--------------------tokenId : " + tokenId);
        return tokenId;
    }

    @Override
    public String getSwiftContainerList(String token) {

        HttpClient client = new DefaultHttpClient();
        String url = "/openstack/swift/container/list";
        HttpGet get = new HttpGet( swiftUrl + url );
        LOGGER.info( "API接口位置===="+get );
        String response = "";

        try {
            get.addHeader( "Content-Type", "application/json;charset=" + CODE_ENCODING );
            get.addHeader( "Accept", "application/json" );
            get.addHeader( "tokenId", token );
            // 转码,防止中文乱码
            HttpResponse res = client.execute( get );

            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println( "--------------------Get " + url + " ResultCode : " + statusCode );
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString( entity, CODE_ENCODING );
            System.out.println( "--------------------response : " + response );
        } catch (Exception e) {
            LOGGER.error("执行testGetSwiftContainerList()出现异常，异常原因:"+e.toString()  );
        }
        return response;
    }

    @Override
    public String createContainer(String tokenId, String containerName) {
        HttpClient client = new DefaultHttpClient();
        String url = "/openstack/swift/container/create";
        ContainerVO containerVO = new ContainerVO();
        containerVO.setName(containerName);
        HttpPut put = new HttpPut(swiftUrl + url);
        String response = "";
        try {
            put.addHeader("Content-Type", "application/json;charset=" + "UTF-8");
            put.addHeader("Accept", "application/json");
            put.addHeader("tokenId", tokenId);
            String clazzToJson = JacksonUtil.toJson(containerVO);   // 转码,防⽌中⽂乱码
            StringEntity s = new StringEntity(clazzToJson, "UTF-8");
            put.setEntity(s);   HttpResponse res = client.execute(put);
            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("--------------------Put " + url + " ResultCode : " + statusCode);
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString(entity, "UTF-8");
            System.out.println("--------------------response : " + response);
        } catch (Exception e) {
            LOGGER.error("执行testCreateContainer() 出现异常，异常原因:"+e.toString()  );
        }
        return response;
    }

    @Override
    public String deleteContainerIfEmpty(String tokenId, String containerName) {

        HttpClient client = new DefaultHttpClient();
        String url = "/openstack/swift/container/deleteIfEmpty" + "/" + containerName;
        HttpDelete delete = new HttpDelete(swiftUrl + url);
        String response = "";
        try {
            delete.addHeader("Content-Type", "application/json;charset=" + CODE_ENCODING);
            delete.addHeader("Accept", "application/json");
            delete.addHeader("tokenId", tokenId);

            // 转码,防止中文乱码
            HttpResponse res = client.execute(delete);
            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("--------------------Delete " + url + " ResultCode : " + statusCode);
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString(entity, CODE_ENCODING);
            System.out.println("--------------------response : " + response);
        } catch (Exception e) {
            LOGGER.error("执行testDeleteContainerIfEmpty()出现异常，异常原因:"+e.toString()  );
        }
        return  response;
    }

    @Override
    public String getSwiftObjectList(String containerName, String token) {
        HttpClient client = new DefaultHttpClient();
        String url = "/openstack/swift/object/listWithParam/" + containerName;
        HttpGet get = new HttpGet( swiftUrl + url );
        String response = "";

        try {
            get.addHeader( "Content-Type", "application/json;charset=" + CODE_ENCODING );
            get.addHeader( "Accept", "application/json" );
            get.addHeader( "tokenId", token );
            // 转码,防止中文乱码
            HttpResponse res = client.execute( get );

            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println( "--------------------Get " + url + " ResultCode : " + statusCode );
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString( entity, CODE_ENCODING );
            System.out.println( "--------------------response : " + response );
        } catch (Exception e) {
            LOGGER.error( "testGetSwiftObjectList()出现异常，异常原因:" + e.toString() );
        }
        return response;
    }

    @Override
    public String deleteObject(String container, String obj, String token) {
        HttpClient client = new DefaultHttpClient();
        String objectName = "";
        try {
            objectName = new String(obj.getBytes("utf-8"), "gbk");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        String url = "/openstack/swift/object/delete" + "/" + container + "/" + objectName;
        HttpDelete delete = new HttpDelete(swiftUrl + url);
        String response = "";

        try {
            delete.addHeader("Content-Type", "application/json;charset=" + CODE_ENCODING);
            delete.addHeader("Accept", "application/json");
            delete.addHeader("tokenId", token);
            // 转码,防止中文乱码
            HttpResponse res = client.execute(delete);

            int statusCode = res.getStatusLine().getStatusCode();
            System.out.println("--------------------Delete " + url + " ResultCode : " + statusCode);
            HttpEntity entity = res.getEntity();
            response = EntityUtils.toString(entity, CODE_ENCODING);
            System.out.println("--------------------response : " + response);
        } catch (Exception e) {
            LOGGER.error( "testDeleteObject()出现异常，异常原因:" + e.toString() );
        }
        return response;
    }
}
